/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2000-2001 Intel Corporation. All Rights Reserved.
//
//  Description:
//      Intel(R) JPEG library for X platform 
//
********************************************************************************/
#include "_ijx.h"

/******************************************************************************
// Name:            ijInitFrameSpecInv
// Description:     Decode frame info of JPEG
// Input Arguments:
//         pStream: Identifies IJBITTREAMSTATE data structure.
// Output Arguments:
//    pDecodeState: Identifies IJDECODESTATE strcuture.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_F_INSUFFICIENTBUF
//                  IJX_RTCODE_E_ERRPARAM
//                  
******************************************************************************/
IJXRESULT ijInitMitionFrameInv(IJBITTREAMSTATE *pStream,
                               IJDECODESTATE   *pDecodeState)
{
    pStream->nNumValidPrefetchedBits=0;
    pStream->nMarker = IJX_MARKER_NONE;
    pDecodeState->procSpec.funcDecompress=(PFUNCODEC)ijDecompress_Motion_Indiv;
    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijInitFrameSpecInv
// Description:     Decode frame information from code stream
// Input Arguments:
// nDesiredImageMode:
//                  Specifies the desired image color mode for decoding.
//         pStream: Identifies IJBITTREAMSTATE data structure.
// Output Arguments:
//    pDecodeState: Identifies IJDECODESTATE strcuture.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_F_INSUFFICIENTBUF
//                  IJX_RTCODE_E_ERRPARAM
//                  
******************************************************************************/
IJXRESULT ijInitFrameSpecInv(int nDesiredImageMode,
                            IJBITTREAMSTATE *pStream,
                            IJDECODESTATE *pDecodeState)
{
    int nMCUWidth, nMCUHeight;
    int nImageMCUStep, nBlksInMCU;
    BOOL bMCUInterleave;
    IJFRAMESPEC *pFrameSpec=&(pDecodeState->frameSpec);
    IJCOMPSPEC  *pCompSpec=pDecodeState->compSpec;
    IIPIMAGESPEC *pImageSpec=&(pDecodeState->imageSpec);
    IJDEPROCESSSPEC *pProcSpec=&(pDecodeState->procSpec);

    pStream->nNumValidPrefetchedBits=0;

    if (8!=pFrameSpec->nPrecision) {
        return IJX_RTCODE_E_NOTSUPPORTEDPRECISION;
    }

    pImageSpec->nPrecision=pFrameSpec->nPrecision;
    pDecodeState->nPrecision=pFrameSpec->nPrecision;
    pImageSpec->nWidth  = pFrameSpec->nWidth;
    pImageSpec->nHeight = pFrameSpec->nHeight;
    pImageSpec->nNumComponent = pFrameSpec->nNumComps;
    pImageSpec->nBitsPerpixel=pImageSpec->nPrecision*pImageSpec->nNumComponent;
    
    switch (pFrameSpec->nSOF) {
        case IJX_MARKER_SOF0:
            pDecodeState->nJPEGCodeMode|=IJX_MODE_BASELINE;
            pProcSpec->funcDecompress=(PFUNCODEC)ijDecompress_BaseLine;
            if ( (IJX_MODE_MOTION_MASK&pDecodeState->nJPEGCodeMode)&&!(IJX_MODE_MOTION_INDIV&pDecodeState->nJPEGCodeMode) ) {
                bMCUInterleave=FALSE;
            } else {
                bMCUInterleave=TRUE;
            }
            break;
        case IJX_MARKER_SOF2:
            pDecodeState->nJPEGCodeMode|=IJX_MODE_PROGRESSIVE;
            pProcSpec->funcDecompress=(PFUNCODEC)ijDecompress_Progressive;
            bMCUInterleave=FALSE;
            break;
        case IJX_MARKER_SOFV:
            if (IJX_MODE_MOTION_DIFF&pDecodeState->nJPEGCodeMode) {
                pProcSpec->funcDecompress=(PFUNCODEC)ijDecompress_Motion_Diff;
                bMCUInterleave=FALSE;
            } else if (IJX_MODE_MOTION_BRIEF&pDecodeState->nJPEGCodeMode) {
                pProcSpec->funcDecompress=(PFUNCODEC)ijDecompress_Motion_Brief;
                bMCUInterleave=FALSE;
            } else {
                pProcSpec->funcDecompress=(PFUNCODEC)ijDecompress_Motion_Indiv;
                bMCUInterleave=TRUE;
            }
            pProcSpec->funcMotionDiffDecoder=pProcSpec->funcMotionDiffFirst;
            break;
        default:
            return IJX_RTCODE_ERROR;
    }

    if (1==pFrameSpec->nNumComps) {
        nMCUWidth=8;
        nMCUHeight=8;
        nImageMCUStep=8;
        nBlksInMCU=1;
        pImageSpec->nColorMode=IIP_CM_GRAY;
        pImageSpec->nSamplingMode=IIP_SM_NONE;
        pProcSpec->funcAdjustMCUBuf=(PFUNCADJUSTMCUBUFFER)ijAdjustMCUBufferInv_1;
        pProcSpec->funcCopyROI=ijxCopy_8u_C1R;
        pProcSpec->funcMCUColorConvert=(PFUNCCCINV_MCU_16S8U)ijAdd128_8x8_16s8u_C1;
        pProcSpec->funcMCUTransform=ijTransformInv_MCU_16s_C1;

        pProcSpec->funcMotionDiffFirst=(PFUNCODEC)ijMotionDiffDecoder_MCU_First_16s_C1;
        pProcSpec->funcMotionDiffDecoder=(PFUNCODEC)ijMotionDiffDecoder_MCU_First_16s_C1;
        pProcSpec->funcMotionDiffRefine=(PFUNCODEC)ijMotionDiffDecoder_MCU_Refine_16s_C1;

        pProcSpec->funcHuffmanDecoder=(PFUNCHUFFMANCODER_BLS)ijHuffmanDecode_Gray_BLS;
		printf("Gray BLS\n");
        pProcSpec->funcHuffmanPDCDecoder=(PFUNCHUFFMANCODER_PDC)ijHuffmanDecode_Gray_DC;
        bMCUInterleave=FALSE;
    } 
    else if (3==pFrameSpec->nNumComps) {
        pProcSpec->funcAdjustMCUBuf=(PFUNCADJUSTMCUBUFFER)ijAdjustMCUBufferInv_3;

        if( (1==pCompSpec[0].nHSampling) && (1==pCompSpec[0].nVSampling) &&
            (1==pCompSpec[1].nHSampling) && (1==pCompSpec[1].nVSampling) &&
            (1==pCompSpec[2].nHSampling) && (1==pCompSpec[2].nVSampling) ){
            //444
            nMCUWidth=8;
            nMCUHeight=8;
            nBlksInMCU=3;
            pImageSpec->nSamplingMode=IIP_SM_NONE;
            pProcSpec->funcHuffmanPDCDecoder=(PFUNCHUFFMANCODER_PDC)ijHuffmanDecode_444_DC;
            pProcSpec->funcMCUTransform=ijTransformInv444_MCU_16s_C3;

            pProcSpec->funcMotionDiffFirst=(PFUNCODEC)ijMotionDiffDecoder_MCU444_First_16s_C3;
            pProcSpec->funcMotionDiffDecoder=(PFUNCODEC)ijMotionDiffDecoder_MCU444_First_16s_C3;
            pProcSpec->funcMotionDiffRefine=(PFUNCODEC)ijMotionDiffDecoder_MCU444_Refine_16s_C3;

            if (IIP_CM_BGR&nDesiredImageMode) {
                nImageMCUStep=24;
                pImageSpec->nColorMode=IIP_CM_BGR;
                pProcSpec->funcCopyROI=ijxCopy_8u_C3R;
                pProcSpec->funcMCUColorConvert=ippiYCbCr444ToBGRLS_MCU_16s8u_P3C3;
            } else if (IIP_CM_BGRA&nDesiredImageMode) {
                nImageMCUStep=32;
                pImageSpec->nColorMode=IIP_CM_BGRA;
                pProcSpec->funcCopyROI=ijxCopy_8u_C4R;
                pProcSpec->funcMCUColorConvert=ippiYCbCr444ToBGRALS_MCU_16s8u_P3C3;
                pImageSpec->nNumComponent = 4;
                pImageSpec->nBitsPerpixel=pImageSpec->nPrecision*pImageSpec->nNumComponent;
            } else if (IIP_CM_BGR555&nDesiredImageMode) {
#if IPPJPVER==1
                    return IJX_RTCODE_E_NOTSUPPORTEDCOMPNUM;
#else     
                nImageMCUStep=16;
                pImageSpec->nBitsPerpixel=16;
                pImageSpec->nColorMode=IIP_CM_BGR555;
                pProcSpec->funcCopyROI=ijxCopy_16u_C1R;
                pProcSpec->funcMCUColorConvert=(PFUNCCCINV_MCU_16S8U)ippiYCbCr444ToBGR555LS_MCU_16s16u_P3C3;
#endif
            } else if (IIP_CM_BGR565&nDesiredImageMode) {
#if IPPJPVER==1
                    return IJX_RTCODE_E_NOTSUPPORTEDCOMPNUM;
#else     
                nImageMCUStep=16;
                pImageSpec->nBitsPerpixel=16;
                pImageSpec->nColorMode=IIP_CM_BGR565;
                pProcSpec->funcCopyROI=ijxCopy_16u_C1R;
                pProcSpec->funcMCUColorConvert=(PFUNCCCINV_MCU_16S8U)ippiYCbCr444ToBGR565LS_MCU_16s16u_P3C3;
#endif
            } else {
                return IJX_RTCODE_ERROR;
            }
            pProcSpec->funcHuffmanDecoder=(PFUNCHUFFMANCODER_BLS)ijHuffmanDecode_444_BLS;
			printf("444 BLS\n");
        }
        else if( (2==pCompSpec[0].nHSampling) && (1==pCompSpec[0].nVSampling) &&
            (1==pCompSpec[1].nHSampling) && (1==pCompSpec[1].nVSampling) &&
            (1==pCompSpec[2].nHSampling) && (1==pCompSpec[2].nVSampling) ){
            //422
            nMCUWidth=16;
            nMCUHeight=8;
            nBlksInMCU=4;
            pImageSpec->nSamplingMode=IIP_SM_422;
            pProcSpec->funcHuffmanPDCDecoder=(PFUNCHUFFMANCODER_PDC)ijHuffmanDecode_422_DC;
            pProcSpec->funcMCUTransform=ijTransformInv422_MCU_16s_C3;
            pProcSpec->funcMotionDiffFirst=(PFUNCODEC)ijMotionDiffDecoder_MCU422_First_16s_C3;
            pProcSpec->funcMotionDiffDecoder=(PFUNCODEC)ijMotionDiffDecoder_MCU422_First_16s_C3;
            pProcSpec->funcMotionDiffRefine=(PFUNCODEC)ijMotionDiffDecoder_MCU422_Refine_16s_C3;

            if (IIP_CM_BGR&nDesiredImageMode) {
                nImageMCUStep=48;
                pImageSpec->nColorMode=IIP_CM_BGR;
                pProcSpec->funcCopyROI=ijxCopy_8u_C3R;
                pProcSpec->funcMCUColorConvert=ippiYCbCr422ToBGRLS_MCU_16s8u_P3C3;
            } else if (IIP_CM_BGRA&nDesiredImageMode) {
                nImageMCUStep=64;
                pImageSpec->nColorMode=IIP_CM_BGRA;
                pProcSpec->funcCopyROI=ijxCopy_8u_C4R;
                pProcSpec->funcMCUColorConvert=ippiYCbCr422ToBGRALS_MCU_16s8u_P3C3;
                pImageSpec->nNumComponent = 4;
                pImageSpec->nBitsPerpixel=pImageSpec->nPrecision*pImageSpec->nNumComponent;
            } else if (IIP_CM_BGR555&nDesiredImageMode) {
#if IPPJPVER==1
                    return IJX_RTCODE_E_NOTSUPPORTEDCOMPNUM;
#else     
                nImageMCUStep=32;
                pImageSpec->nBitsPerpixel=16;
                pImageSpec->nColorMode=IIP_CM_BGR555;
                pProcSpec->funcCopyROI=ijxCopy_16u_C1R;
                pProcSpec->funcMCUColorConvert=(PFUNCCCINV_MCU_16S8U)ippiYCbCr422ToBGR555LS_MCU_16s16u_P3C3;
#endif
            } else if (IIP_CM_BGR565&nDesiredImageMode) {
#if IPPJPVER==1
                    return IJX_RTCODE_E_NOTSUPPORTEDCOMPNUM;
#else     
                nImageMCUStep=32;
                pImageSpec->nBitsPerpixel=16;
                pImageSpec->nColorMode=IIP_CM_BGR565;
                pProcSpec->funcCopyROI=ijxCopy_16u_C1R;
                pProcSpec->funcMCUColorConvert=(PFUNCCCINV_MCU_16S8U)ippiYCbCr422ToBGR565LS_MCU_16s16u_P3C3;
#endif
            } else {
                return IJX_RTCODE_ERROR;
            }
            pProcSpec->funcHuffmanDecoder=(PFUNCHUFFMANCODER_BLS)ijHuffmanDecode_422_BLS;
			printf("422 BLS\n");
        }
        else if( (2==pCompSpec[0].nHSampling) && (2==pCompSpec[0].nVSampling) &&
            (1==pCompSpec[1].nHSampling) && (1==pCompSpec[1].nVSampling) &&
            (1==pCompSpec[2].nHSampling) && (1==pCompSpec[2].nVSampling) ){
            //411
            nMCUWidth=16;
            nMCUHeight=16;
            nBlksInMCU=6;
            pImageSpec->nSamplingMode=IIP_SM_411;
            pProcSpec->funcHuffmanPDCDecoder=(PFUNCHUFFMANCODER_PDC)ijHuffmanDecode_411_DC;
            pProcSpec->funcMCUTransform=ijTransformInv411_MCU_16s_C3;

            pProcSpec->funcMotionDiffFirst=(PFUNCODEC)ijMotionDiffDecoder_MCU411_First_16s_C3;
            pProcSpec->funcMotionDiffDecoder=(PFUNCODEC)ijMotionDiffDecoder_MCU411_First_16s_C3;
            pProcSpec->funcMotionDiffRefine=(PFUNCODEC)ijMotionDiffDecoder_MCU411_Refine_16s_C3;

            if (IIP_CM_BGR&nDesiredImageMode) {
                nImageMCUStep=48;
                pImageSpec->nColorMode=IIP_CM_BGR;
                pProcSpec->funcCopyROI=ijxCopy_8u_C3R;
                pProcSpec->funcMCUColorConvert=ippiYCbCr411ToBGRLS_MCU_16s8u_P3C3;
            } else if (IIP_CM_BGRA&nDesiredImageMode) {
                nImageMCUStep=48;
                pImageSpec->nColorMode=IIP_CM_BGRA;
                pProcSpec->funcCopyROI=ijxCopy_8u_C4R;
                pProcSpec->funcMCUColorConvert=ippiYCbCr411ToBGRALS_MCU_16s8u_P3C3;
                pImageSpec->nNumComponent = 4;
                pImageSpec->nBitsPerpixel=pImageSpec->nPrecision*pImageSpec->nNumComponent;
            } else if (IIP_CM_BGR555&nDesiredImageMode) {
#if IPPJPVER==1
                    return IJX_RTCODE_E_NOTSUPPORTEDCOMPNUM;
#else     
                nImageMCUStep=32;
                pImageSpec->nBitsPerpixel=16;
                pImageSpec->nColorMode=IIP_CM_BGR555;
                pProcSpec->funcCopyROI=ijxCopy_16u_C1R;
                pProcSpec->funcMCUColorConvert=(PFUNCCCINV_MCU_16S8U)ippiYCbCr411ToBGR555LS_MCU_16s16u_P3C3;
#endif
            } else if (IIP_CM_BGR565&nDesiredImageMode) {
#if IPPJPVER==1
                    return IJX_RTCODE_E_NOTSUPPORTEDCOMPNUM;
#else     
                nImageMCUStep=32;
                pImageSpec->nBitsPerpixel=16;
                pImageSpec->nColorMode=IIP_CM_BGR565;
                pProcSpec->funcCopyROI=ijxCopy_16u_C1R;
                pProcSpec->funcMCUColorConvert=(PFUNCCCINV_MCU_16S8U)ippiYCbCr411ToBGR565LS_MCU_16s16u_P3C3;
#endif
            } else {
                return IJX_RTCODE_ERROR;
            }
            pProcSpec->funcHuffmanDecoder=(PFUNCHUFFMANCODER_BLS)ijHuffmanDecode_411_BLS;
			printf("411 BLS\n");
        }
        else {
            return IJX_RTCODE_E_NOTSUPPORTEDCOMPNUM;
        }
            
    }
    else {
        return IJX_RTCODE_E_NOTSUPPORTEDCOMPNUM;
    }

    ijInitFrameComponents(pFrameSpec->nNumComps,pCompSpec);
                         
    ijInitMCU(pImageSpec->nWidth, pImageSpec->nHeight, 
              nMCUWidth, nMCUHeight, nImageMCUStep, nBlksInMCU,
              pImageSpec->nSamplingMode, bMCUInterleave,
              &(pDecodeState->mcuSpec));

    /* MCU Counter */
//    pDecodeState->counter.nFrameMCUCounter=0;

    /* Scan Counter */
    pDecodeState->counter.nFrameScanCounter=pDecodeState->counter.nScanCounter;
//    pDecodeState->counter.nTotalScanCounter+=pDecodeState->counter.nScanCounter;

    pDecodeState->counter.nScanCounter=0;
    pDecodeState->counter.nTotalFrameCounter++;

    return IJX_RTCODE_OK;
}


/* EOF */
